package study.activiti.ssh.service.impl;

import java.io.File;

import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipInputStream;

import org.activiti.engine.FormService;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.form.TaskFormData;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.history.HistoricVariableInstance;
import org.activiti.engine.impl.identity.Authentication;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.PvmTransition;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.Task ;
import org.apache.commons.lang3.StringUtils;

import freemarker.template.utility.StringUtil;

import study.activiti.ssh.dao.ILeaveBillDao;
import study.activiti.ssh.domain.Employee;
import study.activiti.ssh.domain.LeaveBill;
import study.activiti.ssh.service.IWorkflowService;
import study.activiti.ssh.utils.SessionContext;
import study.activiti.ssh.web.form.WorkflowBean;


public class WorkflowServiceImpl implements IWorkflowService {
	/**请假申请Dao*/
	private ILeaveBillDao leaveBillDao;
	
	private RepositoryService repositoryService;
	
	private RuntimeService runtimeService;
	
	private TaskService taskService;
	
	private FormService formService;
	
	private HistoryService historyService;
	
	public void setLeaveBillDao(ILeaveBillDao leaveBillDao) {
		this.leaveBillDao = leaveBillDao;
	}

	public void setHistoryService(HistoryService historyService) {
		this.historyService = historyService;
	}
	
	public void setFormService(FormService formService) {
		this.formService = formService;
	}
	
	public void setRuntimeService(RuntimeService runtimeService) {
		this.runtimeService = runtimeService;
	}
	public void setTaskService(TaskService taskService) {
		this.taskService = taskService;
	}

	public void setRepositoryService(RepositoryService repositoryService) {
		this.repositoryService = repositoryService;
	}

	/**  
	 * @Name: newdeploy（方法的名称）
	* @Description: 部署流程定义（zip格式）（方法的描述）
	* @Author: 李超（作者）
	* @Version: V1.00 （版本号）
	* @Create Date: 2016-12-16 （创建日期）
	* @Parameters: 无（方法的入参，如果没有，填写为“无”）
	* @Return: 无（返回值，如果没有，填写为“无”）
	*/
	public void saveNewdeploy(File file, String filename) {
		//创建文件输入流
		FileInputStream fileInputStream = null;
		try {
			fileInputStream = new FileInputStream(file);
			//1、将File流转化成ZipInputStream流
			ZipInputStream zipInputStream = new ZipInputStream(fileInputStream) ;
			//2、发布流程定义（zip格式）
			repositoryService.createDeployment()
							 .name(filename)
							 .addZipInputStream(zipInputStream)
							 .deploy() ;
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**  
	* @Name: findDeploymentList（方法的名称）
	* @Description: 查询部署对象列表（zip格式）（方法的描述）
	* @Author: 李超（作者）
	* @Version: V1.00 （版本号）
	* @Create Date: 2016-12-16 （创建日期）
	* @Parameters: 无（方法的入参，如果没有，填写为“无”）
	* @Return: List<Deployment> 部署对象列表（返回值，如果没有，填写为“无”）
	*/
	public List<Deployment> findDeploymentList() {
		List<Deployment> list = repositoryService.createDeploymentQuery()
						 .orderByDeploymenTime().asc()
						 .list() ;
		return list;
	}

	/**  
	* @Name: findProcessDefinitionList（方法的名称）
	* @Description: 查询流程定义列表（zip格式）（方法的描述）
	* @Author: 李超（作者）
	* @Version: V1.00 （版本号）
	* @Create Date: 2016-12-16 （创建日期）
	* @Parameters: 无（方法的入参，如果没有，填写为“无”）
	* @Return: List<ProcessDefinition> 部署流程定义列表（返回值，如果没有，填写为“无”）
	*/
	public List<ProcessDefinition> findProcessDefinitionList() {
		List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery()
						 .orderByProcessDefinitionVersion().asc()
						 .list() ;
		return list;
	}

	/**  
	* @Name: deleteDeployment（方法的名称）
	* @Description: 根据部署对象id，删除部署对象，级联删除流程资源定义信息（zip格式）（方法的描述）
	* @Author: 李超（作者）
	* @Version: V1.00 （版本号）
	* @Create Date: 2016-12-16 （创建日期）
	* @Parameters: 无（方法的入参，如果没有，填写为“无”）
	* @Return: List<ProcessDefinition> 部署流程定义列表（返回值，如果没有，填写为“无”）
	*/
	public void deleteDeployment(String deploymentId) {
		repositoryService.deleteDeployment(deploymentId, true) ;
	}

	/**  
	* @Name: findImageInputStream（方法的名称）
	* @Description: 获取资源图片的输入流对象（zip格式）（方法的描述）
	* @Author: 李超（作者）
	* @Version: V1.00 （版本号）
	* @Create Date: 2016-12-16 （创建日期）
	* @Parameters: 无（方法的入参，如果没有，填写为“无”）
	* @Return: List<ProcessDefinition> 部署流程定义列表（返回值，如果没有，填写为“无”）
	*/
	public InputStream findImageInputStream(String deploymentId,
			String imageName) {
		//根据部署对象id和图片资源名称获取图片资源的输入流对象
		InputStream in = repositoryService.getResourceAsStream(deploymentId, imageName) ;
		return in;
	}

	/**  
	* @Name: saveStartProcess（方法的名称）
	* @Description: 启动流程实例（方法的描述） （***工作流开发重点：启动流程实例核心操作方法***）
	* @Author: 李超（作者）
	* @Version: V1.00 （版本号）
	* @Create Date: 2016-12-16 （创建日期）
	* @Parameters: WorkflowBean workflowBean 表单提交的bean（方法的入参，如果没有，填写为“无”）
	* @Return: 无（返回值，如果没有，填写为“无”）
	*/
	public void saveStartProcess(WorkflowBean workflowBean) {
		//1、获取请假单id，查询请假单对象
		Long id = workflowBean.getId() ;
		LeaveBill leaveBill = leaveBillDao.findLeaveBillById(id) ;
		//2、更新请假单的请假状态从0变成1（初始录入-->审核中）
		leaveBill.setState(1) ;
		leaveBillDao.updateLeaveBill(leaveBill) ;
		//3、获取流程定义的key
		String key = leaveBill.getClass().getSimpleName() ;
		//4、从Session中获取当前用户名，设置到流程变量，来指定下一个活动节点（用户任务）的办理人
		Employee employee = SessionContext.get() ;
		String assignee = employee.getName() ;
		Map<String, Object> variables = new HashMap<String, Object>() ;
		//设置下一个活动节点（用户任务）的办理人
		variables.put("inputUser", assignee) ;
		//5、使用流程变量设置字符串（格式：LeaveBill.id的形式），让启动的流程实例关联业务（这里为请假业务）
		String objId = key + "." + id ;
		variables.put("objId", objId) ;
		//或使用正在执行的执行对象表中的一个字段BUSINESS_KEY（Activiti提供）存放字符串（格式：LeaveBill.id的形式），让启动的流程实例关联具体的业务
		//6、使用流程定义的key，启动流程实例，同时设置流程变量，和关联业务的字段BUSINESS_KEY
		runtimeService.startProcessInstanceByKey(key, objId, variables) ;
	}

	/**  
	* @Name: findMyPersonalTask（方法的名称）
	* @Description: 查询正在执行的 个人任务列表
	* @Author: 李超（作者）
	* @Version: V1.00 （版本号）
	* @Create Date: 2016-12-16 （创建日期）
	* @Parameters: String loginName 当前登录用户（方法的入参，如果没有，填写为“无”）
	* @Return: List<Task> 返回任务列表（返回值，如果没有，填写为“无”）
	*/
	public List<Task> findMyPersonalTask(String loginName) {
		List<Task> list = taskService.createTaskQuery()
				   .taskAssignee(loginName)
				   .orderByTaskCreateTime().desc()
				   .list() ;
		return list;
	}

	/**  
	* @Name: findTaskFormByTaskId（方法的名称）
	* @Description: 根据任务id获取任务节点中Form Key的值
	* @Author: 李超（作者）
	* @Version: V1.00 （版本号）
	* @Create Date: 2016-12-16 （创建日期）
	* @Parameters: String taskId 任务id（方法的入参，如果没有，填写为“无”）
	* @Return: String 返回Form Key中存放的url请求链接（返回值，如果没有，填写为“无”）
	*/
	public String findTaskFormByTaskId(String taskId) {
		TaskFormData taskFormData = formService.getTaskFormData(taskId) ;
		return taskFormData.getFormKey();
	}

	/**  
	* @Name: findLeaveBillByTaskId（方法的名称）
	* @Description: 使用任务id，获取请假单信息 （***工作流开发重点：根据流程表中的字段（任务id）查询业务数据（请假单信息）***）
	* 重点：使用流程表中的字段（任务id）查找业务数据（请假单表）
	* 步骤：
	* 	1、使用任务id，查询正在执行的任务表，获取流程实例id
	* 	2、使用流程实例id，查询执行对象表，获取BUSSNESS_KEY的值，该值是工作流程与业务的关联字段，存放内容为【流程定义的key（等于请假业务类名）.业务表主键（请假业务表主键id）】
	* 	3、从BUSSNESS_KEY字段中获取请假单主键id
	* 	4、使用请假单主键id，查询请假单信息
	* @Author: 李超（作者）
	* @Version: V1.00 （版本号）
	* @Create Date: 2016-12-16 （创建日期）
	* @Parameters: String taskId 任务id（方法的入参，如果没有，填写为“无”）
	* @Return: LeaveBill 返回请假单信息 Key中存放的url请求链接（返回值，如果没有，填写为“无”）
	*/
	public LeaveBill findLeaveBillByTaskId(String taskId) {
		//使用任务id，查询正在执行的任务表，获取流程实例id
		Task task = taskService.createTaskQuery().taskId(taskId).singleResult() ;
		String processInstanceId = task.getProcessInstanceId() ;
		//使用流程实例id，查询执行对象表，获取BUSSNESS_KEY的值LeaveBill.1
		ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult() ;
		String businessKey = processInstance.getBusinessKey() ;
		//从BUSSNESS_KEY字段中获取请假单主键id：LeaveBill.1
		String leaveBillId = "" ;
		if(StringUtils.isNotBlank(businessKey)) {
			leaveBillId = businessKey.split("\\.")[1] ;
		}
		//使用请假单主键id，查询请假单信息
		LeaveBill leaveBill = leaveBillDao.findLeaveBillById(Long.parseLong(leaveBillId)) ;
		return leaveBill;
	}

	/**  
	* @Name: findOutcomeListByTaskId（方法的名称）
	* @Description: 使用任务id查询ProcessDefinitionEntity对象，获取当前任务完成之后的连线名称
	* @Author: 李超（作者）
	* @Version: V1.00 （版本号）
	* @Create Date: 2016-12-17 （创建日期）
	* @Parameters: 无（方法的入参，如果没有，填写为“无”）
	* @Return: 无（返回值，如果没有，填写为“无”）
	*/
	public List<String> findOutcomeListByTaskId(String taskId) {
		//1、使用任务id，查询任务对象（获取流程定义id：LeaveBill:1:4）
		Task task = taskService.createTaskQuery().taskId(taskId).singleResult() ;
		//2、获取流程定义id
		String processDefinitionId = task.getProcessDefinitionId() ;
		//3、使用流程定义id，查询流程定义实体对象，对应流程定义文件，例如LeaveBill.bpmn文件
		//说明，：ProcessDefinition与ProcessDefinitionEntity的关系
		//ProcessDefinition流程定义对象，对应正在执行的执行对象表：act_ru_execution
		//ProcessDefinitionEntity流程定义实体对象，对应流程定义文件，例如LeaveBill.bpmn
		//public class ProcessDefinitionEntity extends ProcessDefinitionImpl implements ProcessDefinition, PersistentObject, HasRevision
		ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity) repositoryService.getProcessDefinition(processDefinitionId) ;
		//4、获取当前的活动：使用任务对象获取流程实例id->根据流程实例id获取流程实例对象->根据流程实例对象获取当前活动id->根据当前活动id，获取当前活动对象
		String processInstanceId = task.getProcessInstanceId() ;
		ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult() ;
		String activityId = processInstance.getActivityId() ;
		ActivityImpl currentActivity = processDefinitionEntity.findActivity(activityId) ;
		//5、获取当前活动完成之后连线的名称
		List<String> outcomeList = null ;
		//使用当前活动对象，获取当前活动完成之后的连线对象
		List<PvmTransition> pvmList = currentActivity.getOutgoingTransitions() ;
		//使用获取到的连线对象，获取连线的名称
		if(pvmList != null && pvmList.size() > 0) {
			outcomeList = new ArrayList<String>() ;
			for (PvmTransition pvmTransition : pvmList) {
				//获取连线对象中name属性的值
				String outcome = (String) pvmTransition.getProperty("name") ;
				if(StringUtils.isNotBlank(outcome)) {
					//如果有连线分支，获取连线分支的连线名称
					outcomeList.add(outcome) ;
				} else {
					//如果没有连线分支，为唯一连线设置默认值
					outcomeList.add("默认提交") ;
				}
			}
		}
		return outcomeList;
	}

	/**  
	* @Name: saveSubmitTask（方法的名称）
	* @Description: 提交任务（方法的描述）
	* 操作：使用任务id，完成当前人的个人任务
	* 完成任务之前：
	* 	1、保存批注信息（向act_hi_comment表中添加批注信息），用于记录对当前申请人的审核信息
	* 		扩展：
	* 			如果使用jbpm开发：其提供的数据库表（18张），没有提供与批注信息相关的表，需要自己创建历史审核记录表
	* 			历史审核记录表字段：
	* 				主键id	审核时间	审核人	审核意见	申请单id（完成多对一的映射，一个申请单可以有多条批注信息）
	* 			如果使用Activiti开发，也可以自己创建存储历史审核记录相关的表
	* 			不过Activiti提供的数据库表（23张）中，提供了历史审核记录表（act_hi_comment），直接用即可
	* 	2、根据连线的名称设置流程下一步的走向
	* 		如果连线的名称是“默认提交”，即没有连线分支，直接提交
	* 		如果连线名称不是“默认提交”，设置流程变量，按照连线的名称，控制流程的走向
	* 			流程变量的名称：outcome
	* 			流程变量的值：连线的名称
	* 当任务完成之后：
	* 	指定下一个任务的办理人，已经使用类进行指定
	* 	判断流程是否结束，如果流程执行结束，更新请假单表的状态从1变成2（审核中1->审核完成2）
	* @Author: 李超（作者）
	* @Version: V1.00 （版本号）
	* @Create Date: 2016-12-17 （创建日期）
	* @Parameters: 无（方法的入参，如果没有，填写为“无”）
	* @Return: 无（返回值，如果没有，填写为“无”）
	*/
	public void saveSubmitTask(WorkflowBean workflowBean) {
		//获取任务id
		String taskId = workflowBean.getTaskId() ;
		//保存批注信息：taskService.addComment(任务id,流程实例id,批注信息)
		//使用任务id，获取任务对象，从而获取流程实例id
		Task task = taskService.createTaskQuery().taskId(taskId).singleResult() ;
		String processInstanceId = task.getProcessInstanceId() ;
		/**
		 * 注意：添加批注的时候，由于Activiti底层代码使用：
		 * String userId = Authentication.getAuthenticatedUserId(); //需要我们提前设置进去，即Authentication.getAuthenticatedUserId(当前任务的审核人);
		 * CommentEntity comment = new CommentEntity();
		 * comment.setUserId(userId); //设置当前任务的审核人：通常谁登陆系统，能够对待审核的任务进行提交，审核人就是谁，即当前登录人即为任务审核人
		 */
		//设置当前任务的审核人
		Authentication.setAuthenticatedUserId(SessionContext.get().getName()) ;
		taskService.addComment(taskId, processInstanceId, workflowBean.getComment()) ;
		//获取连线的名称
		String outcome = workflowBean.getOutcome() ;
		//如果连线名称不是“默认提交”，设置流程变量，按照连线的名称，控制流程的走向
		if(StringUtils.isNotBlank(outcome) && !"默认提交".equals(outcome)) {
			//流程变量的名称：outcome
			//流程变量的值：连线的名称
			Map<String, Object> variables = new HashMap<String, Object>() ;
			variables.put("outcome", outcome) ;
			//提交当前人的个人任务，同时设置流程变量
			taskService.complete(taskId, variables) ;
		} else {
			//如果连线的名称是“默认提交”，即没有连线分支，直接提交
			//使用任务id完成当前人的个人任务
			taskService.complete(taskId) ;
		}
		//获取请假单id
		Long id = workflowBean.getId() ;
		//查询流程对象
		ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
					  .processInstanceId(processInstanceId)
					  .singleResult() ;
		//如果流程实例对象为空，则流程执行结束，更新请假单表的状态从1变成2（审核中1->审核完成2）
		if(processInstance == null) {
			LeaveBill leaveBill = leaveBillDao.findLeaveBillById(id) ;
			leaveBill.setState(2) ;
			leaveBillDao.updateLeaveBill(leaveBill) ;
		}
	}

	/**  
	* @Name: findCommentByTaskId（方法的名称）
	* @Description: 使用当前任务id查询历史批注信息
	* @Author: 李超（作者）
	* @Version: V1.00 （版本号）
	* @Create Date: 2016-12-18 （创建日期）
	* @Parameters: 无（方法的入参，如果没有，填写为“无”）
	* @Return: 无（返回值，如果没有，填写为“无”）
	*/
	public List<Comment> findCommentByTaskId(String taskId) {
		/**
		 * 查询历史批注信息：
		 * 方式一：使用历史任务id查询历史批注信息
		 * 步骤：
		 * 		1、使用任务id获取任务对象
		 * 		2、使用任务对象获取流程实例id
		 * 		3、使用流程实例id获取历史任务列表
		 * 		4、遍历获取历史任务id
		 * 		5、使用历史任务id查询历史批注信息
		 * 方式二：使用流程实例id查询历史批注信息
		 * 步骤：
		 * 		1、使用任务id获取任务对象
		 * 		2、使用任务对象获取流程实例id
		 * 		3、使用流程实例id查询历史批注信息
		 */
		List<Comment> commentList = null ;
		Task task = taskService.createTaskQuery().taskId(taskId).singleResult() ;
		String processInstanceId = task.getProcessInstanceId() ;
		//方式一：使用历史任务id查询历史批注信息
		//List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery().processInstanceId(processInstanceId).list() ;
		//if(list != null && list.size() > 0) {
		//	commentList = new ArrayList<Comment>() ;
		//	for(HistoricTaskInstance hti : list) {
		//		//历史任务id
		//		String hisTaskId = hti.getId() ;
		//		//使用历史任务id，查询历史批注信息
		//		List<Comment> comList = taskService.getTaskComments(hisTaskId) ;
		//		commentList.addAll(comList) ;
		//	}
		//}
		//方式二：使用流程实例id查询历史批注信息
		commentList = taskService.getProcessInstanceComments(processInstanceId) ;
		return commentList;
	}

	/**  
	* @Name: findCommentByBusinessId（方法的名称）
	* @Description: 使用请假申请单id查询历史批注信息（***重点：使用业务表中的字段，查询流程表中的数据）
	* 步骤：
	* 	1、使用请假单id，查询请假单对象，获取请假单类名称，拼接查询条件BUSSNESS_KEY
	* 	2、使用查询条件BUSSNESS_KEY，查询历史流程实例表，获取流程实例id
	* 	       或使用查询条件BUSSNESS_KEY，查询历史流程变量表，获取流程实例id
	* 	3、使用流程实例id，查询历史批注信息
	* @Author: 李超（作者）
	* @Version: V1.00 （版本号）
	* @Create Date: 2016-12-18 （创建日期）
	* @Parameters: 无（方法的入参，如果没有，填写为“无”）
	* @Return: 无（返回值，如果没有，填写为“无”）
	*/
	public List<Comment> findCommentByBusinessId(Long id) {
		LeaveBill leaveBill = leaveBillDao.findLeaveBillById(id) ;
		String objId = leaveBill.getClass().getSimpleName() + "." + id ;
		//1、使用查询条件BUSSNESS_KEY，查询历史流程实例表，获取流程实例id
		//HistoricProcessInstance hpi = historyService.createHistoricProcessInstanceQuery()
		//			  .processInstanceBusinessKey(objId)
		//			  .singleResult() ;
		//String processInsatnceId = hpi.getId() ;
		//2、使用查询条件BUSSNESS_KEY，查询历史流程变量表，获取流程实例id
		HistoricVariableInstance hvi = historyService.createHistoricVariableInstanceQuery()
					  .variableValueEquals("objId", objId) //使用流程变量的名称和流程变量的值进行查询
					  .singleResult();
		String processInstanceId = hvi.getProcessInstanceId() ;
		List<Comment> commentList = taskService.getProcessInstanceComments(processInstanceId) ;
		return commentList;
	}

	/**  
	* @Name: findProcessDefinitionByTaskId（方法的名称）
	* @Description: 使用任务id，获取流程定义对象
	* @Author: 李超（作者）
	* @Version: V1.00 （版本号）
	* @Create Date: 2016-12-18 （创建日期）
	* @Parameters: String taskId 任务id（方法的入参，如果没有，填写为“无”）
	* @Return: ProcessDefinition 返回流程定义对象（返回值，如果没有，填写为“无”）
	*/
	public ProcessDefinition findProcessDefinitionByTaskId(String taskId) {
		Task task = taskService.createTaskQuery().taskId(taskId).singleResult() ;
		String processDefinitionId = task.getProcessDefinitionId() ;
		ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
						 .processDefinitionId(processDefinitionId)
						 .singleResult() ;
		return processDefinition;
	}

	/**  
	* @Name: findCoordinatesByTaskId（方法的名称）
	* @Description: 根据任务id获取当前活动的坐标（工作流重点：获取当前活动的坐标）
	* 步骤：
	* 	1、使用任务id，获取当前执行的任务对象，得到当前任务的key和流程定义id
	* 	2、使用流程定义id，获取流程定义实体对象
	* 	3、使用流程定义实体对象，获取当前任务节点的属性值（坐标x,y,width,height）
	* @Author: 李超（作者）
	* @Version: V1.00 （版本号）
	* @Create Date: 2016-12-18 （创建日期）
	* @Parameters: String taskId 任务id（方法的入参，如果没有，填写为“无”）
	* @Return:Map<String, Object> 返回存放坐标的Map集合（返回值，如果没有，填写为“无”）
	*/
	public Map<String, Object> findCoordinatesByTaskId(String taskId) {
		//存放坐标
		Map<String, Object> map = new HashMap<String, Object>() ;
		//使用任务id，获取任务对象
		Task task = taskService.createTaskQuery().taskId(taskId).singleResult() ;
		//获取流程定义id
		String processDefinitionId = task.getProcessDefinitionId() ;
		//使用流程定义id，获取流程定义实体对象（对应bpmn资源文件）
		ProcessDefinitionEntity processDefinitionEntity 
				  = (ProcessDefinitionEntity) repositoryService.getProcessDefinition(processDefinitionId) ;
		//获取流程实例id
		String processInstanceId = task.getProcessInstanceId() ;
		//使用流程定义id，获取流程实例对象
		ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
					  .processInstanceId(processInstanceId).singleResult() ;
		//从流程实例对象中获取当前活动id
		String activitiId = processInstance.getActivityId() ;
		//根据当前活动id，获取当前活动对象
		ActivityImpl currentActiviti = processDefinitionEntity.findActivity(activitiId) ;
		//获取当前活动的坐标
		map.put("x", currentActiviti.getX()) ;
		map.put("y", currentActiviti.getY()) ;
		map.put("width", currentActiviti.getWidth()) ;
		map.put("height", currentActiviti.getHeight()) ;
		return map;
	}

}
